#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H

#include <cstddef>

namespace StructLib
{
    template <typename T>
    class SmartPointer
    {
    protected:
            T *m_pointer;
    public:
        SmartPointer(T *p = NULL)
        {
            std::cout << "SmartPointer()" << std::endl;
            m_pointer = p;
        }

        SmartPointer(const SmartPointer<T>& obj)
        {
            std::cout << "SmartPointer(obj)" << std::endl;

            m_pointer = obj.m_pointer;
            const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
        }

        SmartPointer<T>& operator=(const SmartPointer<T>& obj)
        {
            std::cout << "operator=" << std::endl;
            if (this != &obj)
            {
                delete m_pointer;
                m_pointer = obj.m_pointer;
                const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
            }

            return *this;
        }

        T* operator->()
        {
            return m_pointer;
        }

        T& operator*()
        {
            return *m_pointer;
        }

        bool IsNull()
        {
            return (NULL == m_pointer);
        }

        ~SmartPointer()
        {
            std::cout << "this is ~SmartPointer()" << std::endl;
            delete m_pointer;
        }
    };
}


#endif // !SMARTPOINTER_H
